package a;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;

@Component
@Aspect
@Order(3)
public class Aspects {
//    @Pointcut("execution(public void a.TestService.test())")
//    public void pointcut(){}

    @Around("execution(public void a.TestService.test())")
    public Object logExecuteTime(ProceedingJoinPoint pjp){
//        System.out.println("Before and After invoking method myMethod");
        Object rtValue = null;
        try{
            Object[] args = pjp.getArgs();
            LocalDateTime startTime = LocalDateTime.now(); //  Before 获取当前时间
            rtValue = pjp.proceed(args);        // execute method
            LocalDateTime endTime = LocalDateTime.now(); // 获取另一个时间 AfterReturning
            Duration duration = Duration.between(startTime, endTime);
            long executeDuration = duration.getSeconds();
            System.out.println(ConsoleColors.GREEN+"the duration of execution is "+executeDuration + " seconds"+ConsoleColors.RESET);
            return rtValue;
        }catch (Throwable t){
            System.out.println("Exception thrown in method"); //AfterThrowing
            throw new RuntimeException(t);
        }finally {
//            System.out.println("Running After Advice.");
        }
    }


    @Around("execution(public boolean a.TestService.definitelyFail())")
    public Object retry(ProceedingJoinPoint pjp){
        Object rtValue = null;
        try{
            int retryTimes = -1;
            Object[] args = pjp.getArgs();
            do{
                rtValue = pjp.proceed(args);        // execute method
                if (!(boolean)rtValue) retryTimes+=1;
            }while ((!(boolean)rtValue) && retryTimes<3);

            System.out.println(ConsoleColors.PURPLE+"function return "+rtValue+" ,after retry " + retryTimes + " times"+ConsoleColors.RESET);
            return rtValue;
        }catch (Throwable t){
            System.out.println("Exception thrown in method"); //AfterThrowing
            throw new RuntimeException(t);
        }finally {
//            System.out.println("Running After Advice.");
        }
    }
}
